package com.gitee.huanminabc.jtimerwheel.boot;

import com.gitee.huanminabc.jcommon.reflect.MethodUtil;
import com.gitee.huanminabc.jcommon.str.StringUtil;
import com.gitee.huanminabc.jtimerwheel.annotation.TimerResolver;
import com.gitee.huanminabc.jtimerwheel.annotation.TimerWheel;
import com.gitee.huanminabc.jtimerwheel.base.TimerWheelException;
import com.gitee.huanminabc.jtimerwheel.core.TimerWheelManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;

//用于在springboot框架中启动进行初始化定时器
@Component
@Slf4j
public class TimerSpringInit implements ApplicationListener<ContextRefreshedEvent> {
    //构建定时器
    public void structureTimer(Collection<Object> objects) {
        for (Object o : objects) {
            Class<?> aClass = o.getClass();
            //1.先获取每个方法上的指定注解
            Method[] methods = MethodUtil.getAnnotationMethod(aClass, TimerResolver.class);
            if (methods == null) {
                throw new TimerWheelException(aClass.getName()+"类中没有找到TimerResolver注解");
            }
            for (Method method : methods) {
                try {
                    TimerResolver timerResolver = method.getAnnotation(TimerResolver.class);
                    if (timerResolver == null) {
                        continue;
                    }
                    String key = aClass.getName() + "." + method.getName();
                    String resolver = timerResolver.value();
                    if (StringUtil.isEmpty(resolver)) {
                        throw new TimerWheelException(key+"定时器解析器不能为空");
                    }
                    TimerWheelManager.addTimerSask(resolver, key, () -> {
                        try {
                            method.invoke(o);//执行方法
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            log.error("{}定时器执行异常:", key, e);
                        }
                    });

                } catch (Exception e) {
                    throw new TimerWheelException(e);
                }
            }
        }

    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        //获取所有的NULL注解
        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(TimerWheel.class);
        structureTimer(beansWithAnnotation.values());

    }

}
